package edu.ucla.multicastim.connection;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.Timer;
import java.util.TimerTask;

import edu.ucla.multicastim.util.PacketParserUtil;

public class RendezvousConn {
	
	private static String rendezvousServer = null;
	private static String rootIpAddr = null;
	private static Timer rootTimer = new Timer();
	
	private static Socket socket = null;
	private static BufferedReader in = null;
	private static PrintWriter out = null;

	private static class RefreshThread extends TimerTask {
		@Override
		public void run() {
			byte[] refreshBuf = PacketParserUtil.createPacket("REFRESH", null);
   			out.println(new String(refreshBuf));
		}
	}

	private static void listenForHelloReply(Socket socket, String myAddr) throws IOException {
		String fromServer;
		while ((fromServer = in.readLine()) != null) {
			byte[] pkt = fromServer.getBytes();
			
			String packetType = PacketParserUtil.getPacketType(pkt);
			String packetPayload = PacketParserUtil.getPacketPayload(pkt);

			if(packetType.equals("HELLO-REPLY") && packetPayload.equals(myAddr)) { // If the reply comes back that it's me, start the timer.
	       		int delay = 0;
	       		int period = 1000;
	       		rootTimer.scheduleAtFixedRate(new RefreshThread(), delay, period);
	       		
	       		rootIpAddr = myAddr;
	       		//System.out.println("Setting myself as the root: " + rootIpAddr);
	       	} else {
	       		rootIpAddr = packetPayload;
	       		//System.out.println("The root is: " + rootIpAddr);
	       	}
			break;
		}
	}
	
	private static void writeHelloPacket(Socket socket, String myAddr) {
		byte[] buf = PacketParserUtil.createPacket("HELLO", myAddr);
		out.println(new String(buf));
	}
	
	public static String getRootNode(String myAddr, String rServer) {
		rendezvousServer = rServer;

		try {
	    	socket = new Socket(rendezvousServer, 4444);
			in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
			out = new PrintWriter(socket.getOutputStream(), true);
			
			// Write a Hello Packet to the RendezvousServer, asking for the root.
			writeHelloPacket(socket, myAddr);
			
			// Listen for a HELLO-REPLY with the address for the root server, and use it to set the root
			listenForHelloReply(socket, myAddr);

        } catch (UnknownHostException e) {
            System.err.println("Don't know about host: " + rendezvousServer);
            return null;
        } catch (IOException e) {
			e.printStackTrace();
			return null;
		}
        
		return rootIpAddr;
	}
}